package view;

import java.rmi.RemoteException;

import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;

import server.FirewallSession;

import server.FirewallException;
import server.Log;


/**
 * Class is responsible for the logger table building.
 */
public class LoggerTable extends JTable
{
	/**
	 * 
	 */
	private static final long serialVersionUID = -1077083104420394516L;

	/**
	 * server controller
	 */
	public FirewallSession UI;
	
	/* Current logger table */
	public static LoggerTable currentLoggerTable = null;
	
	/* Column names */
	private final static String columnNames[] = 
		{"Time", "Direction", "Source IP", "Destination IP", "Source port", "Destination port", "Protocol", 
		 "Rule port", "Rule protocol", "Status" };
	
	/* Table data */
	public static Log[] loggerData = null;
		
	/**
	 * C'tor
	 * Create table with scroll.
	 * Size is defined hard coded.
	 */
	public LoggerTable(FirewallSession ui)
	{
		super(Settings.windowDepth, columnNames.length);
		this.UI = ui;
		currentLoggerTable = this;
	    setAutoResizeMode (JTable.AUTO_RESIZE_OFF);
		build();
	}
	
	/**
	 * Create table header.
	 */
	public JTableHeader getLoggerTableHeader()
	{
		TableColumn column = null;
		for (int i = 0; i < columnNames.length; i++)
		{
		    column = getColumnModel().getColumn(i);
		    column.setHeaderValue(columnNames[i]);
		}
		
		return getTableHeader();	
	}
	
	/**
	 * Cancel cell editing for user.
	 */
	public boolean isCellEditable(int row, int column) 
	{
		return false;
	}

	/**
	 * Fill the table.
	 */
	public void build()
	{

		
		getLoggerData();
		
		if(loggerData != null)
		{
			/* Add new rows if it's needed */
			int diff = loggerData.length - getModel().getRowCount();
			
			/* Clear the previous data */
			((DefaultTableModel)getModel()).setRowCount(0);
			if(diff > 0)
			{
				((DefaultTableModel)getModel()).setRowCount(loggerData.length);
			}
			else
			{
				((DefaultTableModel)getModel()).setRowCount(Settings.DEFAULT_LOGGER_WINDOW_DEPTH);
			}
			Settings.statsAccepted =0 ;
			Settings.statsDenied = 0;
			for(int i = 0; i < loggerData.length; i++)
			{
				int j = 0;
				this.setValueAt(loggerData[i].time,      i, j++);
				this.setValueAt(loggerData[i].direct,    i, j++);
				this.setValueAt(loggerData[i].sourceIp,  i, j++);
				this.setValueAt(loggerData[i].sourcePort,  i, j++);
				this.setValueAt(loggerData[i].destIp,    i, j++);
				this.setValueAt(loggerData[i].destPort,  i, j++);
				
				if (loggerData[i].type == Log.typeOpt.IP){
					this.setValueAt(loggerData[i].protocol,  i, j++);
				}
				else{
					j++;
				}
				
				if   (loggerData[i].type == Log.typeOpt.CONTEXT){
					this.setValueAt(loggerData[i].rulePort,      i, j++);
					this.setValueAt(loggerData[i].ruleProtocol,  i, j++);
				}
				else{ 
					j= j + 2;
				}
				
				this.setValueAt(loggerData[i].action,  i, j++);
				
				if ( loggerData[i].action == Log.actionOpt.DENY ){
					Settings.statsDenied ++;
				}
				else if ( loggerData[i].action == Log.actionOpt.ACCEPT ){
					Settings.statsAccepted ++ ;
				}
					
			}			
		}
		else /*if(loggerData != null)*/
		{
			/* Clear the previous data */			
			((DefaultTableModel)getModel()).setRowCount(0);
			((DefaultTableModel)getModel()).setRowCount(Settings.DEFAULT_LOGGER_WINDOW_DEPTH);
		}
	}
	
	/**
	 * Take the data from UI.
	 */
	private void getLoggerData()
	{
		try {
			switch(Settings.currentFilterType)
			{
			case ALL:
				LoggerTable.loggerData = UI.getLogs(Settings.historyDepth);			
				break;
			case PROTOCOL:
				LoggerTable.loggerData =
					UI.getLogs(Settings.historyDepth, Settings.filterProtocol);
				break;
			case IP:
				LoggerTable.loggerData =
					UI.getLogs(Settings.historyDepth, Settings.filterIP, Settings.filterPort,Settings.filterDir);
				break;	
			}
		} catch (RemoteException e) {
			ErrorFrame.AddError("Failed to get log data:" + e.getMessage(), new JFrame());
		} catch (FirewallException e) {
			ErrorFrame.AddError("Failed to get log data:"  + e.getMessage(), new JFrame());
		}
	}
}
